﻿// description  : 单例容器接口
// author       : tristan
// created      : 2011/3/11
// contact      : snaprack@gmail.com

namespace RBAC
{
    using System.Web;

    /// <summary>
    /// 实体暂存容器接口
    /// </summary>
    public interface IShortHolder<T> where T : new()
    {
        /// <summary>
        /// 尝试获得实例
        /// </summary>
        bool TryGet(ref T instance);
        /// <summary>
        /// 注册一个实例, 如果不存在，则创建并保存
        /// </summary>
        T Register();
    }

    /// <summary>
    /// 实体暂存容器工厂
    /// </summary>
    public static class HolderFactory
    {
        public static IShortHolder<T> Creat<T>() where T : new()
        {
            return new HttpContextHolder<T>();
        }
    }

    /// <summary>
    /// 使用HttpContext来作为实体暂存容器, 实现每次http请求产生一个且只产生一个实例。
    /// 适用存放于一段特定生命区间内而不是全局性质的单例实体--(弱化的单例)
    /// </summary>
    public class HttpContextHolder<T> : IShortHolder<T> where T : new()
    {
        const string REGISTER_KEY = "i'm tristan";

        public bool TryGet(ref T instance)
        {
            object obj = HttpContext.Current.Items[REGISTER_KEY];
            if (obj != null)
            {
                instance = (T)obj;
            }
            return instance != null;
        }

        public T Register()
        {
            T instance = new T();
            HttpContext.Current.Items.Remove(REGISTER_KEY);
            HttpContext.Current.Items.Add(REGISTER_KEY, instance);
            return instance;
        }
    }
}
